from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium.webdriver.edge.service import Service as EdgeService

from utils.logger import Log
from utils.path_manager import path_manager
import os

log = Log()


class GetDriver(object):
    driver = None
    current_browser_type = None

    @classmethod
    def get_driver(cls, browser_type="chrome"):
        """获取WebDriver实例，使用单例模式
        
        Args:
            browser_type: 浏览器类型，默认为chrome
        """
        # 如果driver已存在但browser_type不同，则关闭现有driver并创建新的
        if cls.driver is not None and cls.current_browser_type != browser_type:
            cls.close()

        if cls.driver is None:
            # 记录当前使用的browser_type
            cls.current_browser_type = browser_type

            if browser_type == "chrome":
                options = webdriver.ChromeOptions()
                options.add_argument('--no-sandbox')  # 解决DevToolsActivePort文件不存在的报错
                options.add_argument('--ignore-certificate-errors')  # 忽略证书错误
                options.add_argument('--disable-gpu')  # 谷歌文档提到需要加上这个属性来规避bug
                options.add_argument('--disable-infobars')  # 禁止策略化
                options.add_argument('--disable-dev-shm-usage')
                options.add_argument('--disable-features=NetworkService')
                options.add_argument("--disable-features=VizDisplayCompositor")

                # 如果配置了driver路径，使用Service
                if os.path.exists(path_manager.driver_path):
                    s = Service(path_manager.driver_path)
                    cls.driver = webdriver.Chrome(service=s, options=options)
                else:
                    cls.driver = webdriver.Chrome(options=options)
            elif browser_type == "firefox":
                options = webdriver.FirefoxOptions()
                # 如果配置了driver路径，使用Service
                if os.path.exists(path_manager.firefox_driver_path):
                    s = FirefoxService(path_manager.firefox_driver_path)
                    cls.driver = webdriver.Firefox(service=s, options=options)
                else:
                    cls.driver = webdriver.Firefox(options=options)

            elif browser_type == "ie":
                # 如果配置了driver路径，使用Service
                if os.path.exists(path_manager.ie_driver_path):
                    from selenium.webdriver.ie.service import Service as IeService
                    s = IeService(path_manager.ie_driver_path)
                    cls.driver = webdriver.Ie(service=s)
                else:
                    cls.driver = webdriver.Ie()

            elif browser_type == "edge":
                options = webdriver.EdgeOptions()
                # 如果配置了driver路径，使用Service
                if os.path.exists(path_manager.edge_driver_path):
                    s = EdgeService(path_manager.edge_driver_path)
                    cls.driver = webdriver.Edge(service=s, options=options)
                else:
                    cls.driver = webdriver.Edge(options=options)

            elif browser_type == "chrome_headless":
                chrome_options = webdriver.ChromeOptions()
                chrome_options.add_argument('--headless')
                chrome_options.add_argument('--no-sandbox')
                chrome_options.add_argument('--disable-dev-shm-usage')
                chrome_options.add_argument('--disable-gpu')

                # 如果配置了driver路径，使用Service
                if os.path.exists(path_manager.driver_path):
                    s = Service(path_manager.driver_path)
                    cls.driver = webdriver.Chrome(service=s, options=chrome_options)
                else:
                    cls.driver = webdriver.Chrome(options=chrome_options)

            else:
                log.error(
                    "找不到{0}浏览器, 应从中选取一个:'ie', 'firefox', 'edge', 'chrome' , 'chrome_headless'".format(
                        browser_type))
                raise ValueError(f"不支持的浏览器类型: {browser_type}")

            cls.driver.maximize_window()

        return cls.driver

    @classmethod
    def close(cls):
        """关闭WebDriver实例"""
        if cls.driver is not None:
            cls.driver.quit()
            cls.driver = None
